home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene 96
/
Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso
/
misc
/
coding
/
rtvbe210
/
pmode.h
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-23
|
14KB
|
398 lines
/****************************************************************************
*
* PM/Lite Library
*
* Copyright (C) 1996 SciTech Software.
* All rights reserved.
*
* Filename: $Workfile: pmode.h $
* Version: $Revision: 1.1 $
*
* Language: ANSI C
* Environment: Real mode and 16/32 bit Protected Mode under MSDOS
*
* Description: Header file for the DOS extender independant protected
* mode programming library. This library will need to be
* included in all programs that use SciTech Software's
* products that are to be compiled in protected mode.
*
* This library provides pre-built selectors for the BIOS
* data area and VGA frame buffer, and methods for allocating
* your own selectors for physical memory. It also returns
* appropriate selectors for accessing memory allocated in
* the low DOS 1Mb memory area, and routines for accessing
* memory through a selector and offset. By using selectors
* for accessing memory outside of the applications linear
* address space, your code will be fully DPMI compliant and
* will run under Windows 3.1 and OS/2 2.x DOS boxes.
*
* Works with the following:
*
* Real Mode DOS (large memory model)
*
* 16 bit Extenders:
*
* Windows 3.1
* Borland DPMI16
*
* 32 bit Extenders:
*
* Windows 3.1 (Win32s)
* Windows '95 (Win32)
* Phar Lap TNT DOS Extender
* Symantec DOSX
* FlashTek X-32/X-32VM
* Borland DPMI32
* Rational DOS/4GW
* DJGPP go32 for GNU C++ * NO SELECTORS YET!! *
*
* Currently supports the following compilers:
*
* Borland C++ 3.1
* Borland C++ 4.0, 16 bit
* Borland C++ 4.0, 32 bit
* Microsoft Visual C++ 1.5, 16 bit
* Microsoft Visual C++ 1.5, 32 bit
* Symantec C++ 6.1, 16 bit
* Symantec C++ 6.1, 32 bit
* Watcom C++ 10.0, 16 bit
* Watcom C++ 10.0, 32 bit
* Metaware High C++ 3.21, 32 bit
* DJGPP port of GNU C++, 32 bit * NO SELECTORS YET!! *
*
* $Date: 10 Apr 1996 18:15:40 $ $Author: KendallB $
*
****************************************************************************/
#ifndef __PMODE_H
#define __PMODE_H
#ifndef __DEBUG_H
#include "debug.h"
#endif
/*--------------------------- Macros and Typedefs -------------------------*/
/* You will need to define one of the following before you compile this
* library for it to work correctly with the DOS extender that you are
* using when compiling for extended DOS:
*
* DPMI16 - Borland's DPMI16 DOS Power Pack Extender
* TNT - Phar Lap TNT DOS Extender
* DOSX - Symantec C++ DOSX
* X32VM - Flashtek X-32/X-32VM
* DPMI32 - Borland's DPMI32 DOS Power Pack Extender
* DOS4GW - Rational DOS/4GW and DOS/4GW Professional
* DJGPP - DJGPP port of GNU C++
*
* If none is specified, we will automatically determine which operating
* system is being targetted and the following will be defined (provided by
* debug.h header file):
*
* __MSDOS16__ - Default for 16 bit MSDOS mode
* __MSDOS32__ - Default for 32 bit MSDOS
* __WINDOWS16__ - Default for 16 bit Windows
* __WINDOWS32__ - Default for 32 bit Windows
*
* One of the following will be defined automatically for you to select
* which memory model is in effect:
*
* REALMODE - 16 bit real mode (large memory model)
* PM286 - 16 protected mode (large memory model)
* PM386 - 32 protected mode (flat memory model)
*/
#if defined(TNT) || defined(DOSX) || defined(X32VM) || defined(DPMI32) \
|| defined(DOS4GW) || defined(DJGPP) || defined(__WINDOWS32__) \
|| defined(__MSDOS32__)
#define PM386
#elif defined(DPMI16) || defined(__WINDOWS16__)
#define PM286
#else
#define REALMODE
#endif
#pragma pack(1)
/* Provide definitions for the real mode register structures passed to
* the PM_int86() and PM_int86x() routines.
*/
#if defined(REALMODE) || defined(PM286)
#include <dos.h>
typedef union REGS RMREGS;
typedef struct SREGS RMSREGS;
#else
struct _RMWORDREGS {
ushort ax, bx, cx, dx, si, di, cflag, pad1;
};
struct _RMBYTEREGS {
uchar al, ah, bl, bh, cl, ch, dl, dh;
};
typedef union {
struct _RMWORDREGS x;
struct _RMBYTEREGS h;
} RMREGS;
typedef struct {
ushort es;
ushort cs;
ushort ss;
ushort ds;
} RMSREGS;
#endif
struct _PMDWORDREGS {
ulong eax,ebx,ecx,edx,esi,edi,cflag;
};
struct _PMWORDREGS {
ushort ax,ax_hi;
ushort bx,bx_hi;
ushort cx,cx_hi;
ushort dx,dx_hi;
ushort si,si_hi;
ushort di,di_hi;
ushort cflag,cflag_hi;
};
struct _PMBYTEREGS {
uchar al, ah; ushort:16;
uchar bl, bh; ushort:16;
uchar cl, ch; ushort:16;
uchar dl, dh; ushort:16;
};
typedef union {
struct _PMDWORDREGS e;
struct _PMWORDREGS x;
struct _PMBYTEREGS h;
} PMREGS;
typedef struct {
ushort es;
ushort cs;
ushort ss;
ushort ds;
ushort fs;
ushort gs;
} PMSREGS;
/* Define a macro for creating physical base addresses from segment:offset */
#define MK_PHYS(s,o) (((ulong)(s) << 4) + (ulong)(o))
/* Define the different types of modes supported. This is a global variable
* that can be used to determine the type at runtime which will contain
* one of these values.
*/
typedef enum {
PM_realMode,
PM_286,
PM_386,
} PM_mode_enum;
/* Define a macro for changing the default stack size. For some compilers
* and extenders this is done at link time, for others you need to change
* a global variable (Borland C++, X-32 with any compiler). For compilers
* that do it on the command line, this expands to empty.
*/
#ifdef __WINDOWS__
#define DECLARE_STACK(s16,s32)
#elif defined(__TURBOC__)
#define DECLARE_STACK(s16,s32) \
extern uint _stklen = s16;
#elif defined(X32VM)
#define DECLARE_STACK(s16,s32) \
uint int _x32_stack_size = s32;
#else
#define DECLARE_STACK(s16,s32)
#endif
#if defined(__WINDOWS32__)
#define PMAPI _DLLASM /* 'C' calling conventions for Win32 */
#elif defined(__WINDOWS16__)
#define PMAPI _DLLAPI /* Pascal calling conventions for Win16 */
#else
#define PMAPI _ASMAPI /* 'C' calling conventions otherwise */
#endif
/*--------------------------- Function Prototypes -------------------------*/
#ifdef __cplusplus
extern "C" { /* Use "C" linkage when in C++ mode */
#endif
/* Routine to return either PM_realMode, PM_286 or PM_386 */
int PMAPI PM_getModeType(void);
/* Routines to access data through a selector and offset. For real mode
* and 16 bit protected mode (and also Win32), the offset can only be a
* maximum of 64k.
*/
uchar PMAPI PM_getByte(uint s, uint o);
ushort PMAPI PM_getWord(uint s, uint o);
ulong PMAPI PM_getLong(uint s, uint o);
void PMAPI PM_setByte(uint s, uint o, uchar v);
void PMAPI PM_setWord(uint s, uint o, ushort v);
void PMAPI PM_setLong(uint s, uint o, ulong v);
/* Routines for copying data between the applications data space and
* memory accessible through a selector and offset.
*/
void PMAPI PM_memcpynf(void *dst,uint src_s,uint src_o,uint n);
void PMAPI PM_memcpyfn(uint dst_s,uint dst_o,void *src,uint n);
/* Routine to return a selector to the BIOS data area at segment 0x40 */
uint PMAPI PM_getBIOSSelector(void);
/* Routine to return a selector to the VGA frame buffer. The selector
* will map to the correct portion of video memory depending on the
* current video mode (0x3, 0x7 or graphics).
*/
uint PMAPI PM_getVGASelector(void);
/* Routines to return specific selectors to the VGA frame buffer memory */
uint PMAPI PM_getVGAColorTextSelector(void);
uint PMAPI PM_getVGAMonoTextSelector(void);
uint PMAPI PM_getVGAGraphSelector(void);
/* Routines to map/free physical memory into the current DS segment. After
* the mapping has been allocated, it cannot be freed. Hence you should
* only allocate the mapping once and cache the value for use by other
* parts of your application. If this cannot be done, this function will
* return a NULL pointer.
*
* This routine will also work for memory addresses below 1Mb, but the
* memory cannot cross the 1Mb boundary.
*/
void * PMAPI PM_mapPhysicalAddr(ulong base,ulong limit);
/* Routine to load save default data segment selector value into a code
* segment variable, and another to load the value into the DS register.
*/
void PMAPI PM_loadDS(void);
void PMAPI PM_saveDS(void);
/* Routine to get a selector:offset for accessing a low 1Mb memory block.
* You dont need to free this pointer, but in 16 bit protected mode
* the selector allocated will be re-used the next time this routine is
* called. If you need a permanent selector, allocate it with
* PM_createSelector instead.
*/
void PMAPI PM_mapRealPointer(uint *sel,uint *off,uint r_seg,uint r_off);
/* Routine to create an arbritray selector to physical memory. In 16 bit
* protected mode you can pass a 32 bit limit to create a 32 bit
* protected mode data selector.
*/
uint PMAPI PM_createSelector(ulong base,ulong limit);
void PMAPI PM_freeSelector(uint sel);
/* Routine to create 32 bit code segment alias selector from a data
* selector. This is only useful for 16 bit Windows code that
* needs to be able to call 32 bit protected mode code in a USE32 segment.
* The selector can be freed with PM_freeSelector();
*/
#ifdef __WINDOWS16__
uint PMAPI PM_createCode32Alias(uint sel);
#endif
/* Routine to allocate a block of conventional memory below the 1Mb
* limit so that it can be accessed from real mode. Ensure that you free
* the segment when you are done with it.
*
* This routine returns a selector and offset to the segment that has been
* allocated, and also returns the real mode segment and offset which can
* be passed to real mode routines. Will return 0 if memory could not be
* allocated.
*
* Please note that with some DOS extenders, memory allocated with the
* following function cannot be freed, hence it will be allocated for the
* life of your program. Thus if you need to call a bunch of different
* real-mode routines in your program, allocate a single large buffer at
* program startup that can be re-used throughout the program execution.
*/
int PMAPI PM_allocRealSeg(uint size,uint *sel,uint *off,uint *r_seg,uint *r_off);
void PMAPI PM_freeRealSeg(uint sel,uint off);
/* Routine to call a real mode assembly language procedure. Register
* values are passed in and out in the 'regs' and 'sregs' structures. We
* do not provide any method of copying data from the protected mode stack
* to the real mode stack, so if you need to pass data to real mode, you will
* need to write a real mode assembly language hook to recieve the values
* in registers, and to pass the data through a real mode block allocated
* with the PM_allocRealSeg() routine.
*/
void PMAPI PM_callRealMode(uint seg,uint off, RMREGS *regs,RMSREGS *sregs);
/* Routines to generate real mode interrupts using the same interface that
* is used by int86() and int86x() in realmode. This routine is need to
* call certain BIOS and DOS functions that are not supported by some
* DOS extenders. No translation is done on any of the register values,
* so they must be correctly set up and translated by the calling program.
*
* Normally the DOS extenders will allow you to use the normal int86()
* function directly and will pass on unhandled calls to real mode to be
* handled by the real mode handler. However calls to int86x() with real
* mode segment values to be loaded will cause a GPF if used with the
* standard int86x(), so you should use these routines if you know you
* want to call a real mode handler.
*/
int PMAPI PM_int86(int intno, RMREGS *in, RMREGS *out);
int PMAPI PM_int86x(int intno, RMREGS *in, RMREGS *out,RMSREGS *sregs);
/* Routines to generate native interrupts (ie: protected mode interrupts
* for protected mode apps) using an interface the same as that use by
* int86() and int86x() in realmode. These routines are required because
* many 32 bit compilers use different register structures and different
* functions causing major portability headaches. Thus we provide our
* own and solve it all in one fell swoop, and we also get a routine to
* put stuff into 32 bit registers from real mode ;-)
*/
void PMAPI PM_segread(PMSREGS *sregs);
int PMAPI PM_int386(int intno, PMREGS *in, PMREGS *out);
int PMAPI PM_int386x(int intno, PMREGS *in, PMREGS *out,PMSREGS *sregs);
/* Functions to manage real mode interrupt vectors */
void PMAPI _PM_getRMvect(int intno, long *realisr);
void PMAPI _PM_setRMvect(int intno, long realisr);
/* Function to return the amount of available physical and total memory.
* The results of this function are *only* valid before you have made any
* calls to malloc() and free(). If you need to keep track of exactly how
* much memory is currently allocated, you need to call this function to
* get the total amount of memory available and then keep track of
* the available memory every time you call malloc() and free().
*/
void PMAPI PM_availableMemory(ulong *physical,ulong *total);
#ifdef __cplusplus
} /* End of "C" linkage for C++ */
#endif
#pragma pack()
#endif /* __PMODE_H */